<?php

/**
 * @author chenshubo
 * 订单售后
 */
namespace App\Service\OrderService\OrderInterfaceService;

use App\Service\AppService\PushOrderSettleMentService;
use App\Service\Code\Normal;
use App\Service\BaseService;
use App\Model\PssModel\OrderSupplier;
use App\Model\PssModel\OrderSupplierGoods;
use App\Model\CommodityModel\SupplierCompany;
use App\Service\TaskServer\TaskWorker;
use App\Model\PssModel\OrderReturnLog;
use App\Model\PssModel\OrderSettlement;
use App\Service\OrderService\OrderMessageService;
use App\Service\OrderService\OrderSupplierEventLogMessageService AS OSELMS;

class OrderAfterSale extends BaseService
{
    const ORDER_AFTER_SALE_APPLY    = 1;
    const ORDER_AFTER_SALE_CANCEL   = 0;
    /**
     * 订单售后处理
     */
    public function index( $param = [] )
    {
        if( empty($param['requestData']) ) {
            return Normal::returnCode(Normal::FAIL,"订单数据不能为空");
        }
        $requestData = $param['requestData'];
        if( empty($requestData['order_sn']) ) {
            return Normal::returnCode(Normal::FAIL,"订单编号不能为空");
        }
        if( empty($requestData['exceptReason']) ) {
            return Normal::returnCode(Normal::FAIL,"exceptReason售后原因不能为空");
        }
        
        //判断是否是后台子订单直接发起取消按钮操作
        if( isset($requestData['isSingleOrder']) && $requestData['isSingleOrder'] == 1 && empty($requestData['orderNo']) ) {
            return Normal::returnCode(Normal::FAIL,"供应商订单号orderNo不能为空");
        }
        
        $param['requestData']['orderSn'] = $requestData['order_sn'];
        unset($param['requestData']['order_sn']);
        
        if(!isset($requestData['after_sale_status'])){
            return Normal::returnCode(Normal::FAIL,"请提交售后状态");
        }
        
        //状态值是否正确
        if( !in_array($requestData['after_sale_status'],[self::ORDER_AFTER_SALE_APPLY,self::ORDER_AFTER_SALE_CANCEL]) ) {
            return Normal::returnCode(Normal::FAIL,"after_sale_status必须要在0/1之间");
        }        
        
        //查询售后订单
        $res = $this->getSupplierOrderLists($param);
        if( $res['code'] != Normal::SUC ) {
            return $res;
        }
        
        //云仓0.9.29 ，何龙产品强制要求追加
        $requestData['afterSaleDescription'] = $requestData['afterSaleDescription'] ?? '';//售后说明
        $requestData['afterSaleAttach']      = $requestData['afterSaleAttach'] ?? '';//附件
        
        
        $res['data']['order']   = $param['requestData'];
        $res['data']['binfo']   = $param['binfo'];
        
        //判断是否是子订单后台操作发起订单直接售后功能
        if( isset($requestData['isSingleOrder']) && $requestData['isSingleOrder'] == 1 ) {
            $orderInfo      = current($res['data']['supplierOrderList']);
            $suppplierList  = $res['data']['suppplierList'];
            $orderGoodsList = $res['data']['newOrderGoods'];
            return $this->singleOrderAfterSale([
                'companyInfo'   => $suppplierList[$orderInfo['company_id']],
                'supplierOrder' => $orderInfo,
                'orderGoods'    => $orderGoodsList[$orderInfo['id']],
                'order'         => $res['data']['order'],
                'binfo'         => $res['data']['binfo']
            ]);
        }
        
        $res['data']['serviceClass']    = static::class;
        $res['data']['serviceMethod']   = "singleOrderAfterSale";
        $res = TaskWorker::instance()->addTask($res['data'],'singleOrder');
        $message = implode(",", array_column($res,'msg'));
        $code = array_column($res, 'code');
        if( !in_array(Normal::SUC, $code) ) {
            return Normal::returnCode(Normal::FAIL,"处理完成；【{$message}】",$res);
        }
        return Normal::returnCode(Normal::SUC,"处理完成；【{$message}】",$res);
    }
    
    /**
     * 单个订单售后
     * @param array $param
     */
    public function singleOrderAfterSale( $param = [] )
    {
        if( empty($param['companyInfo']) || empty($param['supplierOrder']) || empty($param['orderGoods']) || empty($param['order']) || empty($param['binfo']) )
        {
            return Normal::returnCode(Normal::FAIL,"except param companyInfo or supplierOrder or orderGoods or order or binfo");
        }
        
        $companyInfo    = $param['companyInfo'];
        $company_code   = $companyInfo['company_code'];
        $supplierClass  = ucFirst( $companyInfo['OrderDockMode'] == 1 ? 'normal' : $companyInfo['company_code'] );
        $serviceClass   = "App\\Service\\OrderService\\OrderRouteService\\{$supplierClass}";
        if( !class_exists($serviceClass) )
        {
            return Normal::returnCode(Normal::FAIL,"{$serviceClass} not existed");
        }
        
        $requestMethod = 'orderAfterSale';
        if( !method_exists($serviceClass,$requestMethod) )
        {
            return Normal::returnCode(Normal::FAIL,"{$serviceClass} {$requestMethod} methods not existed");
        }
        
        $supplierOrder      = $param['supplierOrder'];
        $orderGoods         = $param['orderGoods'];
        $order              = $param['order'];
        $binfo              = $param['binfo'];
        $param['apiBody']   = $companyInfo['apiBody'];
        $order_supplier_id  = (string)$supplierOrder['id'];
        $after_sale_status  = (int)$order['after_sale_status'];
        $after_sale_remark  = $order['exceptReason'] ??'';
        $afterSaleDescription = $order['afterSaleDescription'] ?? '';
        $afterSaleAttach      = $order['afterSaleAttach'] ?? '';
        
        try {
            
            OrderSupplier::instance()->startTrans();
            
            //添加订单售后申请日志
            $res = OrderReturnLog::instance()->addLog([
                'order_id'          =>  $order_supplier_id,
                'type'              =>  OrderReturnLog::AFTER_APPLY,
                'contents'          =>  "用户:{$binfo['name']}发起了售后申请",
                'system_user_id'    =>  $binfo['bid'],
                'system_user_name'  =>  $binfo['name'],
            ]);
            if( $res['code'] != Normal::SUC ) {
                OrderSupplier::instance()->rollback();
                return $res;
            }
            
            //是否支持自动通过审核，不需要显示二次审核
            $is_auto_aftersale          = (
                $binfo['is_support_aftersale_verify'] == 0 || 
                (isset($order['isAutoAfterSale']) && $order['isAutoAfterSale'] == 1) ||
                $supplierOrder['order_type'] == OrderPay::YW_ORDER_TYPE
                );
            
            //订单是否推送成功给供应商
            $order_push_status          = $supplierOrder['order_push_status'];
            
            //非顶级云仓且推送成功供应商的订单
            $is_success_push_supplier   = $order_push_status == 1 && $supplierOrder['is_top_system'] == 0 ? 1 : 0;
            
            //判断都需要直接通知供应商接口状态
            $is_need_push_upstream      = ($is_auto_aftersale == 1 || $is_success_push_supplier == 1) ? 1 : 0 ;
            
            //售后状态变更
            $res = $this->orderAfterSaleChange($order_supplier_id,$after_sale_status,$after_sale_remark,$is_auto_aftersale,$afterSaleDescription,$afterSaleAttach);
            if( $res['code'] != Normal::SUC ) {
                OrderSupplier::instance()->rollback();
                return $res;
            }
            
            //已经有自动售后的标识情况下，不再覆盖已存在的标识
            if( !isset($param['order']['isAutoAfterSale']) && $binfo['is_support_aftersale_verify'] == 0 ) {
                $param['order']['isAutoAfterSale'] = 1;
            }
            
            //以下这三种情况，都需要直接通知上游接口售后
            /**
             *  供应商订单推送成功的情况下
             *  1、渠道配置了不支持售后二审功能
             *  2、非顶级云仓，售后直接通过
             *  3、存在售后自动过审核标识 
             */
            if( $order_push_status == 1 && $is_need_push_upstream == 1 )
            {
                $res = $serviceClass::instance()->$requestMethod($param);
                OrderSupplier::instance()->where('id',$order_supplier_id)->update([
                    'after_supplier_notify_status'  => $res['code'] == Normal::SUC ? 1 : 2,
                    'after_supplier_notify_remark'  => $res['msg'] ?? '请求失败'
                ]);
                
                if( $res['code'] != Normal::SUC ) {
                    OrderSupplier::instance()->rollback();
                    return $res;
                }
            }
            
            //自动审核通过，写入结算功能
            if( $is_auto_aftersale == 1 && $supplierOrder['isRecoverSettleMentMoney']) 
            {
                //写入结算售后退款数据
                $param['mode'] = PushOrderSettleMentService::SETTLEMENT_MODE_AFTER_SALE;
                if( $supplierOrder['is_channel_settlement'] == 1 || $supplierOrder['is_supplier_settlement'] ==1 ) {
                    $res = PushOrderSettleMentService::instance()->addOrderSettleMentLog($param);
                    if( $res['code'] != Normal::SUC ) {
                        OrderSupplier::instance()->rollback();
                        return $res;
                    }
                }
                OSELMS::instance()->publish(
                    $order_supplier_id,
                    OSELMS::EVENT_TYPE_ORDER_SETTLEMENT_AFTERSALE,
                    '订单发起售后结算'
                    );
            }            
            
            
            OrderSupplier::instance()->commit();
            
            if( $is_auto_aftersale == 1 ) {
                $response = "售后审核通过";
                OrderCancel::instance()->recoverGoodsStock($param);
            } else {

                //判断是否为顶级云仓,顶级云仓售后需要发短信通知对应的业务人员
                if($supplierOrder['is_top_system'] == 1){
                    //发送短信给对应人员
                    OrderMessageService::instance()->publish(1,'',[
                        'order_sn'=> $supplierOrder['order_sn']
                    ]);
                }
                $response = "售后申请提交成功,请稍后查看审核结果";
            }
            
            //写入订单日志行为
            OSELMS::instance()->publish(
                $order_supplier_id,
                $after_sale_status == 1 ? OSELMS::EVENT_TYPE_ORDER_AFTER_SALE_APPLY : OSELMS::EVENT_TYPE_ORDER_AFTER_SALE_CANCEL,
                $after_sale_status == 1 ? "提交售后申请成功":"取消了售后申请 "
                );
            
            return Normal::returnCode(Normal::SUC,$response,[
                'orderItem' => [
                    'orderSn'  => $supplierOrder['order_sn'],
                    'orderNo'  => $supplierOrder['supplier_csn'],
                ]
            ]);
        } catch ( \Throwable $th) {
            OrderSupplier::instance()->rollback();
            return Normal::returnCode(Normal::FAIL,"售后申请失败，异常原因[{$th->getMessage()}]");
        }
    }
    
    /**
     * 获取供应商列表
     * @param array $param
     */
    public function getSupplierOrderLists( $param = [] )
    {
        $bid = $param['binfo']['bid'];
        $requestData = $param['requestData'];
        $query = OrderSupplier::instance()
        ->select(OrderSupplier::instance()->order_fields)
        ->where('bid',$bid)
        ->whereIn('order_status',[1,2])
        ->where('after_sale_status',$requestData['after_sale_status'] == self::ORDER_AFTER_SALE_APPLY ? self::ORDER_AFTER_SALE_CANCEL : self::ORDER_AFTER_SALE_APPLY)
        ->where('order_sn',$requestData['orderSn']);
        
        //如果存在子订单号的情况下 ，需要考虑云仓商城和后台操作单个订单取消或者申请售后的功能
        if( !empty($requestData['orderNo']) ) {
            $query->where('supplier_csn',$requestData['orderNo']);
        }
        
        $supplierOrderList = $query->get()->toArray();
        if( empty($supplierOrderList) ) {
            return Normal::returnCode(Normal::FAIL,"当前订单不存在或已售后");
        }
        
        //获取订单商品
        $osids  = array_column($supplierOrderList,'id');
        $orderGoods = OrderSupplierGoods::instance()
        ->select(OrderSupplierGoods::instance()->goods_fields)
        ->where('bid',$bid)
        ->whereIn('order_id',$osids)
        ->get()
        ->toArray();
        
        if( empty($orderGoods) ) {
            return Normal::returnCode(Normal::FAIL,"获取订单数据失败");
        }
        
        //获取供应商结算数据
        $settlementOrderList = OrderSettlement::instance()
        ->select([
            'id',
            'order_id',
        ])
        ->where('bid',$bid)
        ->whereIn('order_id',$osids)
        ->where('settlement_type',2)
        ->where('settlement_mode',1)
        ->get()
        ->toArray();
        $settlementOrderList = array_column($settlementOrderList, null,'order_id');
        
        $supplierOrderList = array_map(function( & $value ) use ($settlementOrderList){
            //如果存在结算下单数据，则进行退款操作
            $value['isRecoverSettleMentMoney'] = isset($settlementOrderList[$value['id']]) ? true : false;
            return $value;
        },$supplierOrderList);
        
        $newOrderGoods = [];
        foreach ($orderGoods as $item ) {
            $newOrderGoods[$item['order_id']][] = $item;
            unset($item);
        }
        
        //获取供应商清单信息
        $companyIds = array_unique(array_column($supplierOrderList,'company_id'));
        $SupplierCompanyLists = SupplierCompany::instance()->getSupplierListByIds($companyIds);
        $SupplierCompanyLists = array_column($SupplierCompanyLists, null,'company_id');
        
        return Normal::returnCode(Normal::SUC,"订单数据获取成功",[
            'supplierOrderList' => $supplierOrderList,
            'newOrderGoods' => $newOrderGoods,
            'suppplierList' => $SupplierCompanyLists
        ]);
    }
    
    /**
     * 售后申请及自动审核通过公共接口
     * @param string $order_supplier_id
     * @param int $after_sale_status
     * @param string $exceptReason
     * @param int $is_auto_aftersale
     * @param string $afterSaleDescription
     * @param string $afterSaleAttach
     * @return mixed
     */
    public function orderAfterSaleChange(string $order_supplier_id,int $after_sale_status ,string $exceptReason = '', int $is_auto_aftersale,string $afterSaleDescription = '',string $afterSaleAttach = '')
    {
        $time = time();
        $where = [
            ['id','=',$order_supplier_id],
            ['after_sale_status','=',$after_sale_status == self::ORDER_AFTER_SALE_APPLY ? self::ORDER_AFTER_SALE_CANCEL : self::ORDER_AFTER_SALE_APPLY ],
        ];
        
        $data = [
            'after_sale_status'             => $after_sale_status,
            'after_sale_remark'             => $exceptReason,
            'after_sale_time'               => $time,
            'after_verify_status'           => $is_auto_aftersale == 1 ? 1 : 0 ,
            'after_verify_remark'           => $is_auto_aftersale == 1 ? "自动过审核" : '',
            'after_verify_time'             => $is_auto_aftersale == 1 ? time() : 0,
            'after_channel_notify_status'   => 0,
            'after_channel_notify_remark'   => '',
            'after_supplier_notify_status'  => 0,
            'after_supplier_notify_remark'  => '',
            'after_sale_body'               => json_encode([
                'afterSaleDescription'      => $afterSaleDescription,
                'afterSaleAttach'           => $afterSaleAttach
            ],JSON_UNESCAPED_UNICODE),
            'md'                            => $time,
        ];
        $res = OrderSupplier::instance()->edit($where,$data);
        if( !$res ) {
            if( $after_sale_status == self::ORDER_AFTER_SALE_APPLY ) {
                return Normal::returnCode(Normal::FAIL,"不能重复进行操作订单售后申请功能！");
            }
            return Normal::returnCode(Normal::FAIL,"不能重复进行操作订单售后取消功能！");
        }
        return Normal::returnCode(Normal::SUC,"操作成功");
    }
}
